package com.yuntsg.ruiijn.paperana.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 阿里翻译模型接口，主方法：doTranslate，本方法只翻译英对中，参数包含英文文本，最大单词量和GPU集合，一般最大单词量请限定在100。
 * 贾新志 2024.02.29
 */
public class AliTransModelApi {
    public static void main(String[] args) {
        List<String> GPUList = getGPUList();
        String enStr = "Transforming growth factor β (TGF-β) has long been identified with its intensive involvement in early embryonic development and organogenesis, immune supervision, tissue repair, and adult homeostasis. The role of TGF-β in fibrosis and cancer is complex and sometimes even contradictory, exhibiting either inhibitory or promoting effects depending on the stage of the disease. Under pathological conditions, overexpressed TGF-β causes epithelial-mesenchymal transition (EMT), extracellular matrix (ECM) deposition, cancer-associated fibroblast (CAF) formation, which leads to fibrotic disease, and cancer. Given the critical role of TGF-β and its downstream molecules in the progression of fibrosis and cancers, therapeutics targeting TGF-β signaling appears to be a promising strategy. However, due to potential systemic cytotoxicity, the development of TGF-β therapeutics has lagged. In this review, we summarized the biological process of TGF-β, with its dual role in " +
                "fibrosis and tumorigenesis, and the clinical application of TGF-β-targeting therapies. The transforming growth factor-β (TGF-β) is the prototype of the TGF-β family of growth and differentiation factors, which is encoded by 33 genes in mammals and comprises homo- and heterodimers. This review introduces the reader to the TGF-β family with its complexity of names and biological activities. It also introduces TGF-β as the best-studied factor among the TGF-β family proteins, with its diversity of roles in the control of cell proliferation and differentiation, wound healing and immune system, and its key roles in pathology, for example, skeletal diseases, fibrosis, and cancer. Introduction: Transforming Growth Factor-Beta (TGF-β) is a master regulator of numerous cellular functions including cellular immunity. In cancer, TGF-β can function as a tumor promoter via several mechanisms including immunosuppression. Since the immune checkpoint pathways are co-opted in cancer " +
                "to induce T cell tolerance, this review posits that TGF-β is a master checkpoint in cancer, whose negative regulatory influence overrides and controls that of other immune checkpoints.Areas Covered: This review examines therapeutic agents that target TGF-β and its signaling pathways for the treatment of cancer which may be classifiable as checkpoint inhibitors in the broadest sense. This concept is supported by the observations that 1) only a subset of patients benefit from current checkpoint inhibitor therapies, 2) the presence of TGF-β in the tumor microenvironment is associated with excluded or cold tumors, and resistance to checkpoint inhibitors, and 3) existing biomarkers such as PD-1, PD-L1, microsatellite instability and tumor mutational burden are inadequate to reliably and adequately identify immuno-responsive patients. By contrast, TGF-β overexpression is a widespread and profoundly negative molecular hallmark in multiple tumor types.Expert Opinion: TGF-β " +
                "status may serve as a biomarker to predict responsiveness and as a therapeutic target to increase the activity of immunotherapies. The TGF-beta family of cytokines are ubiquitous, multifunctional and essential to survival. They play important roles in growth and development, inflammation and repair and host immunity. The mammalian TGF-beta isoforms (TGF-beta 1, beta 2 and beta 3) are secreted as latent precursors and have multiple cell surface receptors of which at least two mediate signal transduction. Autocrine and paracrine effects of TGF-beta's can be modified by extracellular matrix, neighbouring cells and other cytokines. The vital role of the TGF-beta family is illustrated by the fact that approximately 50% of TGF-beta 1 gene knockout mice die in utero and the remainder succumb to uncontrolled inflammation after birth. TGF-beta 2 and TGF-beta 3 gene knockout mice are not yet described. More recently, novel TGF-beta-like molecules have been described which " +
                "share some of the properties of the mammalian TGF-beta isoforms. The role of TGF-beta in homeostatic and pathogenic processes suggests numerous applications in the diagnosis and treatment of various diseases characterised by inflammation and fibrosis.";
        String cnStr = doTranslate(enStr, 100, GPUList);
        System.out.println(cnStr);

// main
    }

    // 执行翻译，enStr是待翻译的英文字符串，max是每次提交给翻译模型的最大单词数量，提交时以句号为切割点，句子的集合一般不大于100个单词，如果发生翻译的数量不对，则返回为空字符串。GPUList是模型GPU的集合。
    public static String doTranslate(String enStr, int max, List<String> GPUList) {
        List<TransInfoLog> errLogList = new ArrayList<>();
        enStr = enStr.replace("。", ".").replace("，", ",").replace("；", ";").replace("？", "?").replace("：", ":").replaceAll(" +", " ").trim() + " ";
        String[] split = enStr.split(" ");
        List<String> list = new ArrayList<>();
        if (split.length < max) {
            list.add(enStr);
            String translate = getTranslate(list, " ", GPUList, errLogList);
            // 如果有翻译的错误日志，则直接返回空字符串。
            return errLogList.size() > 0 ? "" : translate;
        } else {
            String[] firstSplit = enStr.split("\\. "); // 以句号加空格进行切割
            int sum = 0;
            StringBuilder result = new StringBuilder();
            for (String first : firstSplit) {
                int length = first.split(" ").length;
                if (length > max - 1) {
                    first = first.replace(", ", "㵝. ").replace("? ", "纃. ").replace("; ", "☷. ").replaceAll(" +", " ").trim();
                    String[] middleSplit = first.split("\\. "); // 如果以空格切割的单词数量比设定值多，则将逗号、句号、分号替换为句号，再次以句号进行切割，此为第二种情况，即单以句号仍大于设定值。
                    for (int i = 0; i < middleSplit.length; i++) {
                        String middle = middleSplit[i];
                        // 特殊字符"㵝"、"纃"、"☷"的作用是，先将逗号、句号、分号替换为句号，执行切割后，再还原回来。
                        middle = middle.replace("㵝", ", ").replace("☷", "; ").replace("纃", "? ").replaceAll(" +", " ").trim();
                        middle = (i + 1 == middleSplit.length) ? (middle + ". ") : middle;
                        int len = middle.split(" ").length;
                        if (len > max - 1) {
                            String[] lastSplit = middle.split(" "); // 第三种，如果第二种仍大于设定值，则再次空格切割，而这一次要么直接翻译，要么添加，确保不会出现漏翻译的情况。
                            for (String last : lastSplit) {
                                if (sum + 1 < max) {
                                    list.add(last + " ");
                                    sum += 1;
                                } else {
                                    result.append(getTranslate(list, " ", GPUList, errLogList));
                                    sum = 1;
                                    list.clear();
                                    list.add(last + " ");
                                }
                            }
                        } else if (sum + len < max) {
                            list.add(middle);
                            sum += len;
                        } else {
                            result.append(getTranslate(list, " ", GPUList, errLogList));
                            sum = 0;
                            list.clear();
                            list.add(middle);
                            sum += len;
                        }
                    }
                } else if (sum + length < max) { // 如果原来的以空格进行切割的单词数量总和，加上本次的以空格进行切割的单词数量，仍小于设定值，则直接添加到待翻译里面。否则先把待翻译的执行翻译，再把待翻译的清空，再把总和的置0，再把本次的添加到待翻译中，再把总和的加上本次的数量。
                    list.add(first + ". ");
                    sum += length;
                } else {
                    result.append(getTranslate(list, " ", GPUList, errLogList));
                    sum = 0;
                    list.clear();
                    list.add(first + ". ");
                    sum += length;
                }
            }
            result.append(getTranslate(list, " ", GPUList, errLogList));
            return errLogList.size() > 0 ? "" : result.toString();
        }
    }

    // 英到中的翻译主体，如果有漏翻译的，返回为空字符串。每一个英文句子的集合，一般不大于100个句子，且不可以将多个英文句子整理为一个句子给翻译模型，只能是一个句子一个句子的添加到集合中。
    public static List<String> enToCnTrans(List<String> GPUList, List<String> enList, List<TransInfoLog> errLogList) {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("from", "en");
        map1.put("to", "zh");
        map1.put("q", enList);
        try {
            String body1 = HttpRequest.post(GPUList.get(RandomUtil.randomInt(0, GPUList.size()))).body(JSONUtil.toJsonStr(map1)).contentType("application/json").timeout(5000).execute().body();
            List<String> cnList = JSONUtil.toList(JSONUtil.parseArray(body1), String.class);
            // 理论上，一个英文句子，翻译后只对应一个中文句子，如果数量不相等，可能是有漏翻译的，记录到翻译错误日志中。
            if (cnList.size() == enList.size()) {
                return cnList;
            } else {
                TransInfoLog transInfoLog = new TransInfoLog();
                transInfoLog.setEnList(enList);
                transInfoLog.setCnList(cnList);
                errLogList.add(transInfoLog);
            }
        } catch (HttpException e) {
//            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    // 执行翻译方法中的一个方法，功能是对英文集合进行翻译，并返回连接到一块儿的中文句子。
    public static String getTranslate(List<String> enList, String end, List<String> GPUList, List<TransInfoLog> errLogList) {
        StringBuilder result = new StringBuilder();
        List<String> cnList = enToCnTrans(GPUList, enList, errLogList);
        for (String s : cnList) {
            result.append(s).append(end);
        }
        return result.toString().replace(" （ ", "（").replace(" ） ", "）").replace(" ， ", "，").replace(" ： ", "：").replace(" / / ", "//")
                .replace(" / ", "/").replace(" > < ", "><").replace(" > ", ">").replace(" < ", "<").replace(" \\ ", "\\").replace("\\ ", "\\")
                .replace("。", ".").replace(". ", "。 ").replace("。。 ", "。 ").replace(" - ", "-").replace("）- ", "）-").replace(" ； ", "； ").replace(" 、 ", "、");
    }

    // 阿里翻译模型的GPU链接集合
    public static List<String> getGPUList() {
        List<String> GPUList = new ArrayList<>();
        GPUList.add("http://123.128.12.90:9001/fanyi");
        GPUList.add("http://123.128.12.90:9002/fanyi");
        GPUList.add("http://123.128.12.90:9003/fanyi");
        GPUList.add("http://123.128.12.90:9004/fanyi");
        GPUList.add("http://123.128.12.90:9005/fanyi");
        GPUList.add("http://123.128.12.90:9006/fanyi");
        GPUList.add("http://123.128.12.90:9007/fanyi");
        GPUList.add("http://123.128.12.90:9008/fanyi");
        return GPUList;
    }

    @Data
    // 翻译日志记录信息，包含一个英文和一个中文的集合，当英文的句子多于中文的句子时，说明漏翻译了。
    public static class TransInfoLog {
        private List<String> enList = new ArrayList<>();
        private List<String> cnList = new ArrayList<>();
    }


// end
}
